package 类加载器.自定义类加载器;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * <P> @Author: ideaAdmin
 * <P> TODO: Class
 * <P> TODO: 自定义类加载器
 * <P> Date: 2022/3/31:17:22
 * <P> Description:
 */

public class MyClassLoader extends ClassLoader {
    private String byteCodePath;

    public MyClassLoader() {

    }

    public MyClassLoader(String byteCodePath) {
        this.byteCodePath = byteCodePath;
    }

    public MyClassLoader(ClassLoader parent, String byteCodePath) {
        super(parent);
        this.byteCodePath = byteCodePath;
    }


    @Override
    protected Class<?> findClass(String className) throws ClassNotFoundException {
        BufferedInputStream bis = null;
        ByteArrayOutputStream baos = null;


        try {
            //TODO 获得字节码的完整路径
            String fileName = byteCodePath + className + ".class";

            //TODO 获取输入流
            bis = new BufferedInputStream(new FileInputStream(fileName));

            //TODO 获取输出流 转为字节数组
            baos = new ByteArrayOutputStream();


            //TODO 把读取到的数据写入到内存中
            int len;
            byte[] data = new byte[1024];
            while ((len = bis.read(data)) != -1) {
                baos.write(data, 0, len);
            }

            //TODO 获取内存中的完整的字节数组
            byte[] byteCodes = baos.toByteArray();

            //TODO 调用defineClass 将字节数组的数组转为Class的实例
            Class<?> clazz = defineClass(null, byteCodes, 0, byteCodes.length);

            return clazz;

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(bis != null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(baos != null){
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }

        return null;
    }
}
